package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.entity.AdminMenus;
import com.dingreading.cloud.admin.entity.table.AdminMenusTableDef;
import com.dingreading.cloud.admin.mapper.AdminMenusMapper;
import com.dingreading.cloud.admin.service.AdminMenusService;
import com.dingreading.cloud.common.util.NepUtil;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

import static com.dingreading.cloud.admin.entity.table.AdminRoleMenuTableDef.adminRoleMenu;
import static com.mybatisflex.core.query.QueryMethods.max;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class AdminMenusServiceImpl extends BaseServiceImpl<AdminMenusMapper, AdminMenus, AdminMenusTableDef> implements AdminMenusService {

    @Override
    protected AdminMenusTableDef getTable() {
        return AdminMenusTableDef.adminMenus;
    }

    @Override
    public List<AdminMenus> getAllList() {
        QueryWrapper wrapper = QueryWrapper.create()
                .select()
                .from(table)
                .orderBy(table.parentId.asc(), table.orderNum.asc());
        return getMapper().selectListWithRelationsByQuery(wrapper);
    }

    @Override
    public boolean updateNodes(Long id, String nodes) {
        return UpdateChain.of(AdminMenus.class)
                .set(table.nodes, nodes)
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public List<AdminMenus> getByNodesNotId(String nodes, Long id) {
        QueryCondition condition = table.nodes.likeLeft(nodes);
        if (null != id)
            condition.and(table.id.ne(id));

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.orderNum.asc());
        return getMapper().selectListWithRelationsByQuery(wrapper);
    }

    @Override
    public int dropBean(Long id) {
        return getMapper().deleteById(id);
    }

    @Override
    public List<AdminMenus> getByRoleIdAndEnabled(Long roleId, Integer enabled) {
        QueryWrapper where = QueryWrapper.create()
                .select(adminRoleMenu.menuId)
                .from(adminRoleMenu)
                .where(adminRoleMenu.roleId.eq(roleId));

        QueryCondition condition = QueryCondition.createEmpty();
        if (enabled != null)
            condition.and(table.id.in(where))
                    .and(table.enabled.eq(1));
        else
            condition.and(table.id.in(where));

        QueryWrapper wrapper = QueryWrapper.create()
                .select()
                .from(table)
                .where(condition)
                .orderBy(table.orderNum.asc());
        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public List<AdminMenus> listByRoleIdAndEnabled(List<Long> roleIds, Integer enabled) {
        QueryWrapper where = QueryWrapper.create()
                .select(QueryMethods.distinct(adminRoleMenu.menuId))
                .from(adminRoleMenu)
                .where(adminRoleMenu.roleId.in(roleIds));

        QueryCondition condition = QueryCondition.createEmpty();
        if (enabled != null)
            condition.and(table.id.in(where))
                    .and(table.enabled.eq(1));
        else
            condition.and(table.id.in(where));

        QueryWrapper wrapper = QueryWrapper.create()
                .select()
                .from(table)
                .where(condition)
                .orderBy(table.orderNum.asc());
        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public int getMaxShowOrder(Long parentId) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(max(table.orderNum))
                .from(table)
                .where(table.parentId.eq(parentId));

        Integer integer = getMapper().selectObjectByQueryAs(wrapper, Integer.class);
        return NepUtil.nullToZero(integer);
    }

    @Override
    public AdminMenus getGtOrderNum(Long parentId, Integer orderNum) {
        QueryCondition condition = table.parentId.eq(parentId)
                .and(table.orderNum.gt(orderNum));
        QueryWrapper wrapper = QueryWrapper.create()
                .orderBy(table.orderNum.asc())
                .where(condition);
        List<AdminMenus> list = getMapper().selectListByQuery(wrapper);
        if (CollectionUtils.isNotEmpty(list))
            return list.get(0);
        return null;
    }

    @Override
    public AdminMenus getLtOrderNum(Long parentId, Integer orderNum) {
        QueryCondition condition = table.parentId.eq(parentId)
                .and(table.orderNum.lt(orderNum));
        QueryWrapper wrapper = QueryWrapper.create()
                .orderBy(table.orderNum.desc())
                .where(condition);
        List<AdminMenus> list = getMapper().selectListByQuery(wrapper);
        if (CollectionUtils.isNotEmpty(list))
            return list.get(0);
        return null;
    }

    @Override
    public void updateOrderNum(Long id, Integer orderNum) {
        UpdateChain.of(AdminMenus.class)
                .set(table.orderNum, orderNum)
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public boolean updateEnabled(Long id, Integer enabled) {
        return UpdateChain.of(AdminMenus.class)
                .set(table.enabled, enabled)
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public boolean updateChildEnabled(String nodes, Integer enabled) {
        return UpdateChain.of(AdminMenus.class)
                .set(table.enabled, enabled)
                .where(table.nodes.likeLeft(nodes))
                .update();
    }

}
